package com.leo.tool.jdk.core;

import lombok.SneakyThrows;
import org.junit.Assert;
import org.junit.Test;

import java.lang.Thread.State;

public class ThreadTest {

    @Test
    public void testInterrupt() throws InterruptedException {
        Thread thread = new Thread(() -> sleep(100 * 1000));
        thread.setDaemon(true);
        thread.start();
        Assert.assertEquals(State.RUNNABLE, thread.getState());
        thread.interrupt();
        thread.join();
        Assert.assertEquals(State.TERMINATED, thread.getState());
    }

    @Test
    public void testInterrupt2() throws InterruptedException {
        Thread thread = new Thread(() -> doubleSleep(100 * 1000));
        thread.start();
        Assert.assertEquals(State.RUNNABLE, thread.getState());
        thread.interrupt();
        thread.join(10);
        Assert.assertEquals(State.TIMED_WAITING, thread.getState());
        thread.interrupt();
        thread.join();
        Assert.assertEquals(State.TERMINATED, thread.getState());
    }

    @Test
    public void testJoin() throws InterruptedException {
        Thread thread = new Thread(() -> doubleSleep(100 * 1000));
        thread.start();
        Assert.assertEquals(State.RUNNABLE, thread.getState());

        Thread thread2 = new Thread(() -> join(thread));
        thread2.start();
        thread2.join(10);
        Assert.assertEquals(State.WAITING, thread2.getState());
    }

    private void sleep(long time) {
        // do anything: RUNNING状态不会被interrupt中断
        try {
            Thread.sleep(time);
        } catch (InterruptedException e) {
            // 标记位被清除
            Assert.assertFalse(Thread.currentThread().isInterrupted());
            //线程状态变为RUNNABLE
            Assert.assertEquals(State.RUNNABLE, Thread.currentThread().getState());
        }
    }

    private void doubleSleep(long time) {
        sleep(time);
        sleep(time);
    }

    @SneakyThrows
    private void join(Thread thread) {
        thread.join();
    }

}
